1. Technical Field
The present disclosure relates generally to just-in-time code, and, in particular, to processing unsigned just-in-time code at a device that enforces a code signing requirement.
2. Introduction
Security and performance are some of the most coveted features in technology. The need for better security and performance in computing devices appears with regularity in a score of varying circumstances. And while the growing complexity of software demands higher performance, and the rising prevalence of security threats demands improved security, developers face the increasingly difficult challenge of designing a system that provides improved security and performance. Not an exclusive improvement of either one, but an overall improvement of both. Often, developers improve performance, or security, but rarely both together—typically because enhanced security can hinder performance, and vice versa.
One technique for improving security is code signing. Code signing is the process of digitally signing computer code to allow the system to determine the source (such as an author or publisher) of the code, and/or ensure that the code has not been altered or corrupted. Typically, the signer (e.g., an author or a publisher) generates a message digest of the code and encrypts the digest using a private key. To sign the code, the signer then inserts the encrypted digest and a digital certificate, including a public key that corresponds to the private key, into the code. The user's computer verifies the signature by creating a digest of the code, decrypting the signer's encrypted digest using the public key from the digital certificate, and comparing the results. If the two digests match, the signature is valid. With code signing, impostors and malicious attackers are significantly limited in their ability to usurp resources on the device to execute unauthorized code. Overall, code signing facilitates the identification of genuine applications and creates a better and more trustworthy user experience. Unfortunately, however, code signing is unavailable for code compiled just-in-time.
Just-in-time (JIT) compilation refers to on-demand—or “just-in-time”—translation of computer code into machine instructions. With JIT, translation occurs continuously, and translated code can be cached to increase performance and provide faster code execution. Not surprisingly, JIT is a popular technique for improving the runtime performance of programs.
Nevertheless, JIT suffers from several limitations. First, developers cannot digitally sign code compiled on the fly. As a result, JIT strips a system of its ability to perform code signing vis-à-vis JIT code. In fact, secure systems that enforce code signing requirements are unable to run JIT code. Second, JIT compilers are often subject to memory manipulation attacks: attackers use JIT to create regions of memory at a predictable address, copy their payload into the region of memory, and execute their code. Thus, while JIT provides certain benefits, security limitations can pose significant risks—all of which are aggravated by the absence of code signing technologies.